/**
 * @author: zzj
 * @email: zhazhjie@vip.qq.com
 * @date: 2021-04-19 21:33:58
 * @version: 1.0
 */

/**
 * 首字母大写
 * @param name
 * @returns {string}
 */
function toCapitalize(name) {
  if (!name) return "";
  return name.substring(0, 1).toUpperCase() + name.substring(1);
}

export default {
  name: "crud-template",
  props: {
    callbacks: {
      type: Object,
      default: () => ({})
    },
  },
  data() {
    return {
      tableLoading: false,
      params: {
        currentPage: 1,
        pageSize: 10,
        total: 10
      },
      api: {},
      list: []
    }
  },
  methods: {
    injectApi(api) {
      this.api = api;
      this.getList();
    },
    existMethod(name) {
      return this.$listeners[name];
    },
    getList() {
      let {pageable} = this.$attrs.config || {};
      let {beforeSubmitSearch, afterSubmitSearch, catchSubmitSearch} = this.callbacks;
      if (beforeSubmitSearch && !beforeSubmitSearch(this.params)) return;
      this.tableLoading = true;
      (pageable === false ? this.api.listAll() : this.api.listPage(this.params)).then(res => {
        this.tableLoading = false;
        if (afterSubmitSearch && !afterSubmitSearch(res)) return;
        if (pageable === false) {
          this.list = res.data;
        } else {
          this.list = res.data.records;
          this.params.total = res.data.total;
        }
      }).catch(err => {
        console.error(err);
        this.tableLoading = false;
        if (catchSubmitSearch) catchSubmitSearch(err);
      });
    },
    execCallback(prefix, methodName, ...params) {
      let cb = this.callbacks[prefix + toCapitalize(methodName)];
      if (cb) return cb(...params);
      return true;
    },
    execRequest(data) {
      let {methodName, requestMethod, row, hideLoading, done, msg} = data;
      if (this.existMethod(methodName)) return;
      if (!this.execCallback("before", methodName, row)) return hideLoading && hideLoading();
      this.api[requestMethod](row).then(res => {
        this.execCallback("after", methodName, row, res);
        done && done();
        this.$message.success(msg);
        this.getList();
      }).catch(err => {
        console.error(err);
        this.execCallback("catch", methodName, row, err);
        hideLoading && hideLoading();
      });
    },
    handleSubmitAdd(row, hideLoading, done) {
      this.execRequest({
        row, hideLoading, done,
        methodName: "submitAdd",
        requestMethod: "add",
        msg: "新增成功"
      });
    },
    handleSubmitEdit(row, hideLoading, done) {
      this.execRequest({
        row, hideLoading, done,
        methodName: "submitEdit",
        requestMethod: "updateById",
        msg: "更新成功"
      });
    },
    handleSubmitSearch(params) {
      if (this.existMethod("submitSearch")) return;
      this.params.currentPage = 1;
      this.params = {...this.params, ...params};
      this.getList();
    },
    handleDelete(row, name) {
      this.$confirm('确定要删除[' + (name || row.id) + ']吗?', {
        type: 'warning'
      }).then(() => {
        this.execRequest({
          row: {id: row.id},
          methodName: "submitDelete",
          requestMethod: "deleteById",
          msg: "删除成功"
        });
      });
    },
    handlePageChange() {
      if (this.existMethod("pageChange")) return;
      this.getList();
    }
  },
  mounted() {
    this.$parent.$crudTmp = this;
    this.$parent.$crud = this.$crud;
  },
  render() {
    return (
      <f-crud
        on-submit-add={this.handleSubmitAdd}
        on-submit-edit={this.handleSubmitEdit}
        on-submit-search={this.handleSubmitSearch}
        on-page-change={this.handlePageChange}
        props={{
          tableLoading: this.tableLoading,
          page: this.params,
          data: this.list,
          ...this.$attrs
        }}
        on={this.$listeners}
        scopedSlots={this.$scopedSlots}/>
    )
  }
}
